<?php

namespace app\command;

use app\ArrayToolkit;
use app\client\WeChatClient;
use app\logic\User;
use think\console\Command;
use think\console\Input;
use think\console\Output;

class SyncData extends Command
{
    protected $type = "SyncData";

    protected $weChatClient = null;
    protected function configure()
    {
        parent::configure();
        $this->setName('sync:SyncData')
            ->setDescription('sync weChat User Data');
    }

    protected function execute(Input $input, Output $output)
    {
        $openIds = $this->findAllWeChatUser();
        $users = $this->findUserInfo($openIds);
        $users = ArrayToolkit::index($users, 'openid');

        if (empty($users)) {
            return ;
        }

        $existUsers = $this->getUserLogic()->findAllWeChatUser();
        if (empty($existUsers)) {
            $this->createUser($users);
            return ;
        }

        $existUsers = ArrayToolkit::index($existUsers, 'wechat_open_id');


        $createUsers = array_diff_key($users, $existUsers);
        $this->createUser($createUsers);

        $updateUsers = array_intersect_key($users, $existUsers);
        $this->updateUser($updateUsers, $existUsers);
    }

    public function createUser($users)
    {
        if (empty($users)) {
            return false;
        }

        $groupUsers = array_chunk($users, 100);

        foreach ($groupUsers as $groupUser) {
            $createUsers = [];
            foreach ($groupUser as $user) {
                $createUsers[] = $this->buildUserFields($user);
            }
            $this->getUserLogic()->batchCreateUsers($createUsers);
        }

        return true;
    }

    public function updateUser($users, $existUsers)
    {
        if (empty($users)) {
            return false;
        }

        $groupUsers = array_chunk($users, 100);

        foreach ($groupUsers as $groupUser) {
            $updateUsers = [];
            foreach ($groupUser as $user) {
                $updateUser = $this->buildUserFields($user);
                if (empty($existUsers[$user['openid']])) {
                    continue;
                }
                $updateUser['id'] = $existUsers[$user['openid']]['id'];
                unset($updateUser['password']);
                unset($updateUser['username']);
                unset($updateUser['login_ip']);
                $updateUsers[] = $updateUser;
            }
            $this->getUserLogic()->batchUpdateUser($updateUsers);
        }

        return true;
    }

    protected function buildUserFields($user)
    {
        return [
            'username' => $user['nickname'],
            'nickname' => $user['nickname'],
            'avatar' => $user['headimgurl'],
            'password' => md5('admin123123'),
            'login_ip' => '127.0.0.1',
            'wechat_open_id' => $user['openid'],
        ];
    }

    protected function findAllWeChatUser()
    {
        $userList = [];
        $nextOpenid = 0;
        do {
            $result = $this->getWeChatClient()->searchWeCherUserList($nextOpenid);
            $nextOpenid = $result['next_openid'];
            if (!empty($result['data'])) {
                $userList = array_merge($userList, $result['data']['openid']);
            }
        } while ($result['total'] < $result['count']);

        return $userList;
    }

    protected function findUserInfo($openIds)
    {
        $groupOpenIds = array_chunk($openIds, 100);

        $users = [];
        foreach ($groupOpenIds as $groupOpenId) {
            $userList = [];

            foreach ($groupOpenId as $userOpenId) {
                $userList[] = [
                    'openid' => $userOpenId,
                    'lang' => 'zh_CN',
                ];
            }
            $result = $this->getWeChatClient()->findUserInfoByOpenIds($userList);
            if (!empty($result['user_info_list'])) {
                $users = array_merge($users, $result['user_info_list']);
            }
        }

        return $users;
    }

    protected function getWeChatClient()
    {
        if (empty($this->weChatClient)) {
            $wechat = config('wechat');
            return new WeChatClient($wechat['wechat_app_id'], $wechat['wechat_app_secret']);
        }

        return $this->weChatClient;
    }

    /**
     * @return User
     */
    protected function getUserLogic()
    {
        return app('logic')->logic('User');
    }
}
